Change semantics of bind_evtchn_to_xxx and
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 29 Sep 2005 14:14:03 +0000 (15:14 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 29 Sep 2005 14:14:03 +0000 (15:14 +0100)
unbind_evtchn_from_xxx. The bind now returns the IRQ
number on success. The unbind takes this as a parameter
instead of the event-channel port. Also, unbind closes
down the underlying event-channel port if it is still
live.

Signed-off-by: Keir Fraser <keir@xensource.com>
20 files changed:
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
linux-2.6-xen-sparse/drivers/xen/blktap/common.h
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
linux-2.6-xen-sparse/drivers/xen/netback/common.h
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
linux-2.6-xen-sparse/include/asm-xen/evtchn.h

index 1f94775476b3f3bad7403e047c73e32dbd65fc3c..32294c7bcda6265a573ec9f1029f7386076595b6 100644 (file)
@@ -320,13 +320,19 @@ int bind_evtchn_to_irq(unsigned int evtchn)
 }
 EXPORT_SYMBOL(bind_evtchn_to_irq);
 
-void unbind_evtchn_from_irq(unsigned int evtchn)
+void unbind_evtchn_from_irq(unsigned int irq)
 {
-       int irq = evtchn_to_irq[evtchn];
+       evtchn_op_t op;
+       int evtchn = irq_to_evtchn[irq];
 
        spin_lock(&irq_mapping_update_lock);
 
-       if (--irq_bindcount[irq] == 0) {
+       if ((--irq_bindcount[irq] == 0) && (evtchn != -1)) {
+               op.cmd          = EVTCHNOP_close;
+               op.u.close.dom  = DOMID_SELF;
+               op.u.close.port = evtchn;
+               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+
                evtchn_to_irq[evtchn] = -1;
                irq_to_evtchn[irq]    = -1;
        }
@@ -348,17 +354,16 @@ int bind_evtchn_to_irqhandler(
        irq = bind_evtchn_to_irq(evtchn);
        retval = request_irq(irq, handler, irqflags, devname, dev_id);
        if (retval != 0)
-               unbind_evtchn_from_irq(evtchn);
+               unbind_evtchn_from_irq(irq);
 
-       return retval;
+       return irq;
 }
 EXPORT_SYMBOL(bind_evtchn_to_irqhandler);
 
-void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id)
+void unbind_evtchn_from_irqhandler(unsigned int irq, void *dev_id)
 {
-       unsigned int irq = evtchn_to_irq[evtchn];
        free_irq(irq, dev_id);
-       unbind_evtchn_from_irq(evtchn);
+       unbind_evtchn_from_irq(irq);
 }
 EXPORT_SYMBOL(unbind_evtchn_from_irqhandler);
 
@@ -425,9 +430,8 @@ static unsigned int startup_dynirq(unsigned int irq)
 {
        int evtchn = irq_to_evtchn[irq];
 
-       if (!VALID_EVTCHN(evtchn))
-               return 0;
-       unmask_evtchn(evtchn);
+       if (VALID_EVTCHN(evtchn))
+               unmask_evtchn(evtchn);
        return 0;
 }
 
@@ -435,38 +439,41 @@ static void shutdown_dynirq(unsigned int irq)
 {
        int evtchn = irq_to_evtchn[irq];
 
-       if (!VALID_EVTCHN(evtchn))
-               return;
-       mask_evtchn(evtchn);
+       if (VALID_EVTCHN(evtchn))
+               mask_evtchn(evtchn);
 }
 
 static void enable_dynirq(unsigned int irq)
 {
        int evtchn = irq_to_evtchn[irq];
 
-       unmask_evtchn(evtchn);
+       if (VALID_EVTCHN(evtchn))
+               unmask_evtchn(evtchn);
 }
 
 static void disable_dynirq(unsigned int irq)
 {
        int evtchn = irq_to_evtchn[irq];
 
-       mask_evtchn(evtchn);
+       if (VALID_EVTCHN(evtchn))
+               mask_evtchn(evtchn);
 }
 
 static void ack_dynirq(unsigned int irq)
 {
        int evtchn = irq_to_evtchn[irq];
 
-       mask_evtchn(evtchn);
-       clear_evtchn(evtchn);
+       if (VALID_EVTCHN(evtchn)) {
+               mask_evtchn(evtchn);
+               clear_evtchn(evtchn);
+       }
 }
 
 static void end_dynirq(unsigned int irq)
 {
        int evtchn = irq_to_evtchn[irq];
 
-       if (!(irq_desc[irq].status & IRQ_DISABLED))
+       if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED))
                unmask_evtchn(evtchn);
 }
 
@@ -559,35 +566,36 @@ static void shutdown_pirq(unsigned int irq)
 static void enable_pirq(unsigned int irq)
 {
        int evtchn = irq_to_evtchn[irq];
-       if (!VALID_EVTCHN(evtchn))
-               return;
-       unmask_evtchn(evtchn);
-       pirq_unmask_notify(irq_to_pirq(irq));
+
+       if (VALID_EVTCHN(evtchn)) {
+               unmask_evtchn(evtchn);
+               pirq_unmask_notify(irq_to_pirq(irq));
+       }
 }
 
 static void disable_pirq(unsigned int irq)
 {
        int evtchn = irq_to_evtchn[irq];
-       if (!VALID_EVTCHN(evtchn))
-               return;
-       mask_evtchn(evtchn);
+
+       if (VALID_EVTCHN(evtchn))
+               mask_evtchn(evtchn);
 }
 
 static void ack_pirq(unsigned int irq)
 {
        int evtchn = irq_to_evtchn[irq];
-       if (!VALID_EVTCHN(evtchn))
-               return;
-       mask_evtchn(evtchn);
-       clear_evtchn(evtchn);
+
+       if (VALID_EVTCHN(evtchn)) {
+               mask_evtchn(evtchn);
+               clear_evtchn(evtchn);
+       }
 }
 
 static void end_pirq(unsigned int irq)
 {
        int evtchn = irq_to_evtchn[irq];
-       if (!VALID_EVTCHN(evtchn))
-               return;
-       if (!(irq_desc[irq].status & IRQ_DISABLED)) {
+
+       if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED)) {
                unmask_evtchn(evtchn);
                pirq_unmask_notify(irq_to_pirq(irq));
        }
@@ -637,6 +645,10 @@ void irq_resume(void)
                        BUG_ON(per_cpu(ipi_to_evtchn, cpu)[ipi] != -1);
        }
 
+       /* No IRQ -> event-channel mappings. */
+       for (irq = 0; irq < NR_IRQS; irq++)
+               irq_to_evtchn[irq] = -1;
+
        /* Primary CPU: rebind VIRQs automatically. */
        for (virq = 0; virq < NR_VIRQS; virq++) {
                if ((irq = per_cpu(virq_to_irq, 0)[virq]) == -1)
@@ -676,6 +688,13 @@ void irq_resume(void)
                /* Ready for use. */
                unmask_evtchn(evtchn);
        }
+
+       /* Remove defunct event-channel -> IRQ mappings. */
+       for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) {
+               if ((evtchn_to_irq[evtchn] != -1) &&
+                   (irq_to_evtchn[evtchn_to_irq[evtchn]] == -1))
+                       evtchn_to_irq[evtchn] = -1;
+       }
 }
 
 void __init init_IRQ(void)
@@ -689,11 +708,10 @@ void __init init_IRQ(void)
 
        init_evtchn_cpu_bindings();
 
+       /* No VIRQ or IPI bindings. */
        for (cpu = 0; cpu < NR_CPUS; cpu++) {
-               /* No VIRQ -> IRQ mappings. */
                for (i = 0; i < NR_VIRQS; i++)
                        per_cpu(virq_to_irq, cpu)[i] = -1;
-               /* No VIRQ -> IRQ mappings. */
                for (i = 0; i < NR_IPIS; i++)
                        per_cpu(ipi_to_evtchn, cpu)[i] = -1;
        }
index 03fff886aa8b0376061f4986f61ade2157ab9065..ab8f32e531bc46076027cec3cad98b8444501742 100644 (file)
@@ -65,12 +65,6 @@ static int __do_suspend(void *ignore)
 {
        int i, j, k, fpp;
 
-#ifdef CONFIG_XEN_USB_FRONTEND
-       extern void usbif_resume();
-#else
-#define usbif_resume() do{}while(0)
-#endif
-
        extern int gnttab_suspend(void);
        extern int gnttab_resume(void);
 
@@ -87,7 +81,6 @@ static int __do_suspend(void *ignore)
        int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
 #endif
 
-       extern void xencons_suspend(void);
        extern void xencons_resume(void);
 
        int err = 0;
@@ -147,17 +140,15 @@ static int __do_suspend(void *ignore)
        }
 #endif
 
+       xenbus_suspend();
+
+       gnttab_suspend();
+
 #ifdef __i386__
        mm_pin_all();
        kmem_cache_shrink(pgd_cache);
 #endif
 
-       xenbus_suspend();
-
-       xencons_suspend();
-
-       gnttab_suspend();
-
        HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
        clear_fixmap(FIX_SHARED_INFO);
 
@@ -202,8 +193,6 @@ static int __do_suspend(void *ignore)
 
        time_resume();
 
-       usbif_resume();
-
 #ifdef CONFIG_SMP
        for_each_cpu_mask(i, prev_present_cpus)
                restore_vcpu_context(i, &suspended_cpu_records[i]);
index ffc168d0a0ff822d625e36575fd26ec476eca2b5..4235d3f4fed78bacadce27ccb211bb8695f7155f 100644 (file)
@@ -44,7 +44,7 @@ typedef struct blkif_st {
        unsigned int      handle;
        /* Physical parameters of the comms window. */
        unsigned int      evtchn;
-       unsigned int      remote_evtchn;
+       unsigned int      irq;
        /* Comms information. */
        blkif_back_ring_t blk_ring;
        struct vm_struct *blk_ring_area;
index 15649685d5051dee42f0bbf04758f29e1c066fb7..92e37850b3e6d64cda75abf72aecc2e477c58a48 100644 (file)
@@ -71,8 +71,6 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
        evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
        int err;
 
-       BUG_ON(blkif->remote_evtchn);
-
        if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL )
                return -ENOMEM;
 
@@ -94,13 +92,12 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
        }
 
        blkif->evtchn = op.u.bind_interdomain.port1;
-       blkif->remote_evtchn = evtchn;
 
        sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
        SHARED_RING_INIT(sring);
        BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
 
-       bind_evtchn_to_irqhandler(
+       blkif->irq = bind_evtchn_to_irqhandler(
                blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
        blkif->status = CONNECTED;
 
@@ -109,21 +106,13 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
 
 static void free_blkif(void *arg)
 {
-       evtchn_op_t op = { .cmd = EVTCHNOP_close };
        blkif_t *blkif = (blkif_t *)arg;
 
-       op.u.close.port = blkif->evtchn;
-       op.u.close.dom = DOMID_SELF;
-       HYPERVISOR_event_channel_op(&op);
-       op.u.close.port = blkif->remote_evtchn;
-       op.u.close.dom = blkif->domid;
-       HYPERVISOR_event_channel_op(&op);
+       if (blkif->irq)
+               unbind_evtchn_from_irqhandler(blkif->irq, blkif);
 
        vbd_free(&blkif->vbd);
 
-       if (blkif->evtchn)
-               unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
-
        if (blkif->blk_ring.sring) {
                unmap_frontend_page(blkif);
                free_vm_area(blkif->blk_ring_area);
index 8c1db775ffad87580a26fba577fee435e4ec1b81..209cd6b1013d73707a47aa83da7bd22f7233b85e 100644 (file)
@@ -357,8 +357,9 @@ static void blkif_free(struct blkfront_info *info)
        if (info->ring_ref != GRANT_INVALID_REF)
                gnttab_end_foreign_access(info->ring_ref, 0);
        info->ring_ref = GRANT_INVALID_REF;
-       unbind_evtchn_from_irqhandler(info->evtchn, info); 
-       info->evtchn = 0;
+       if (info->irq)
+               unbind_evtchn_from_irqhandler(info->irq, info); 
+       info->evtchn = info->irq = 0;
 }
 
 static void blkif_recover(struct blkfront_info *info)
@@ -429,10 +430,12 @@ static void blkif_connect(struct blkfront_info *info, u16 evtchn)
 
        err = bind_evtchn_to_irqhandler(
                info->evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
-       if (err != 0) {
+       if (err <= 0) {
                WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
                return;
        }
+
+       info->irq = err;
 }
 
 
index 9dc7a54379a762835fcb35cb7431eb1e53c2f6e6..24388e84e59dd088a2da9f86153033127d1161cc 100644 (file)
@@ -123,7 +123,7 @@ struct blkfront_info
        int backend_id;
        int ring_ref;
        blkif_front_ring_t ring;
-       unsigned int evtchn;
+       unsigned int evtchn, irq;
        struct xlbd_major_info *mi;
        request_queue_t *rq;
        struct work_struct work;
index 3caae4654f67aab6a55f156da89d2db9aabb2a3e..38fa80b55790449477f4743d4aec4718d37edceb 100644 (file)
@@ -46,7 +46,7 @@ typedef struct blkif_st {
        unsigned int      handle;
        /* Physical parameters of the comms window. */
        unsigned int      evtchn;
-       unsigned int      remote_evtchn;
+       unsigned int      irq;
        /* Comms information. */
        blkif_back_ring_t blk_ring;
        struct vm_struct *blk_ring_area;
index 7719b76acc956b0a9a71e5c3a8ff40fcc2a91fdb..85cf5d7362e4d2d0c0ac1f7dc2e6241d0aed99b2 100644 (file)
@@ -71,8 +71,6 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
        evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
        int err;
 
-       BUG_ON(blkif->remote_evtchn);
-
        if ((blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL)
                return -ENOMEM;
 
@@ -93,35 +91,26 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
                return err;
        }
 
-
        blkif->evtchn = op.u.bind_interdomain.port1;
-       blkif->remote_evtchn = evtchn;
 
        sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
        SHARED_RING_INIT(sring);
        BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
 
-       bind_evtchn_to_irqhandler(
+       blkif->irq = bind_evtchn_to_irqhandler(
                blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
-       blkif->status        = CONNECTED;
+
+       blkif->status = CONNECTED;
 
        return 0;
 }
 
 static void free_blkif(void *arg)
 {
-       evtchn_op_t op = { .cmd = EVTCHNOP_close };
        blkif_t *blkif = (blkif_t *)arg;
 
-       op.u.close.port = blkif->evtchn;
-       op.u.close.dom = DOMID_SELF;
-       HYPERVISOR_event_channel_op(&op);
-       op.u.close.port = blkif->remote_evtchn;
-       op.u.close.dom = blkif->domid;
-       HYPERVISOR_event_channel_op(&op);
-
-       if (blkif->evtchn)
-               unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
+       if (blkif->irq)
+               unbind_evtchn_from_irqhandler(blkif->irq, blkif);
 
        if (blkif->blk_ring.sring) {
                unmap_frontend_page(blkif);
index 40d4da5349eff2fa1161ee256eee4c243f8beff8..2402a76ea4e122c2284fd4c0671a672686ebeff7 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/err.h>
 #include "xencons_ring.h"
 
-
 struct ring_head
 {
        u32 cons;
@@ -29,6 +28,7 @@ struct ring_head
        char buf[0];
 } __attribute__((packed));
 
+static int xencons_irq;
 
 #define XENCONS_RING_SIZE (PAGE_SIZE/2 - sizeof (struct ring_head))
 #define XENCONS_IDX(cnt) ((cnt) % XENCONS_RING_SIZE)
@@ -97,32 +97,28 @@ int xencons_ring_init(void)
 {
        int err;
 
+       if (xencons_irq)
+               unbind_evtchn_from_irqhandler(xencons_irq, inring());
+       xencons_irq = 0;
+
        if (!xen_start_info->console_evtchn)
                return 0;
 
-       err = bind_evtchn_to_irqhandler(xen_start_info->console_evtchn,
-                                       handle_input, 0, "xencons", inring());
-       if (err) {
+       err = bind_evtchn_to_irqhandler(
+               xen_start_info->console_evtchn,
+               handle_input, 0, "xencons", inring());
+       if (err <= 0) {
                xprintk("XEN console request irq failed %i\n", err);
                return err;
        }
 
-       return 0;
-}
-
-void xencons_suspend(void)
-{
-
-       if (!xen_start_info->console_evtchn)
-               return;
+       xencons_irq = err;
 
-       unbind_evtchn_from_irqhandler(xen_start_info->console_evtchn,
-                                     inring());
+       return 0;
 }
 
 void xencons_resume(void)
 {
-
        (void)xencons_ring_init();
 }
 
index 1c907cff9cd3a3a8be7600f845fda27d4a29ebda..5150cb8844432b47e7b00d6daee5864754032771 100644 (file)
@@ -50,7 +50,7 @@ typedef struct netif_st {
        u16              rx_shmem_handle;
        grant_ref_t      rx_shmem_ref; 
        unsigned int     evtchn;
-       unsigned int     remote_evtchn;
+       unsigned int     irq;
 
        /* The shared rings and indexes. */
        netif_tx_interface_t *tx;
index c3d525c3f424e3258d9d589c101296bad163426f..b8b495ecb33cbca00c1ea86ef85b0fba1636298c 100644 (file)
@@ -15,18 +15,17 @@ static void __netif_up(netif_t *netif)
        spin_lock_bh(&dev->xmit_lock);
        netif->active = 1;
        spin_unlock_bh(&dev->xmit_lock);
-       (void)bind_evtchn_to_irqhandler(
-               netif->evtchn, netif_be_int, 0, dev->name, netif);
+       enable_irq(netif->irq);
        netif_schedule_work(netif);
 }
 
 static void __netif_down(netif_t *netif)
 {
        struct net_device *dev = netif->dev;
+       disable_irq(netif->irq);
        spin_lock_bh(&dev->xmit_lock);
        netif->active = 0;
        spin_unlock_bh(&dev->xmit_lock);
-       unbind_evtchn_from_irqhandler(netif->evtchn, netif);
        netif_deschedule_work(netif);
 }
 
@@ -203,7 +202,10 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
        }
 
        netif->evtchn = op.u.bind_interdomain.port1;
-       netif->remote_evtchn = evtchn;
+
+       netif->irq = bind_evtchn_to_irqhandler(
+               netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
+       disable_irq(netif->irq);
 
        netif->tx = (netif_tx_interface_t *)netif->comms_area->addr;
        netif->rx = (netif_rx_interface_t *)
@@ -224,21 +226,15 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
 
 static void free_netif_callback(void *arg)
 {
-       evtchn_op_t op = { .cmd = EVTCHNOP_close };
        netif_t *netif = (netif_t *)arg;
 
        /*
-        * These can't be done in netif_disconnect() because at that point
+        * This can't be done in netif_disconnect() because at that point
         * there may be outstanding requests in the network stack whose
         * asynchronous responses must still be notified to the remote driver.
         */
-
-       op.u.close.port = netif->evtchn;
-       op.u.close.dom = DOMID_SELF;
-       HYPERVISOR_event_channel_op(&op);
-       op.u.close.port = netif->remote_evtchn;
-       op.u.close.dom = netif->domid;
-       HYPERVISOR_event_channel_op(&op);
+       if (netif->irq)
+               unbind_evtchn_from_irqhandler(netif->irq, netif);
 
        unregister_netdev(netif->dev);
 
index 732e0d818e746cae0603cca2d81473dbcacbc5e9..abb4524dca6c3674e44dbbb9ca2c8b96961cdc30 100644 (file)
@@ -127,7 +127,7 @@ struct net_private
        spinlock_t   rx_lock;
 
        unsigned int handle;
-       unsigned int evtchn;
+       unsigned int evtchn, irq;
 
        /* What is the status of our connection to the remote backend? */
 #define BEST_CLOSED       0
@@ -815,7 +815,7 @@ connect_device(struct net_private *np, unsigned int evtchn)
        memcpy(dev->dev_addr, np->mac, ETH_ALEN);
        np->evtchn = evtchn;
        network_connect(dev);
-       (void)bind_evtchn_to_irqhandler(
+       np->irq = bind_evtchn_to_irqhandler(
                np->evtchn, netif_int, SA_SAMPLE_RANDOM, dev->name, dev);
        (void)send_fake_arp(dev);
        show_device(np);
@@ -1055,8 +1055,9 @@ static void netif_free(struct netfront_info *info)
                gnttab_end_foreign_access(info->rx_ring_ref, 0);
        info->rx_ring_ref = GRANT_INVALID_REF;
 
-       unbind_evtchn_from_irqhandler(info->evtchn, info->netdev);
-       info->evtchn = 0;
+       if (info->irq)
+               unbind_evtchn_from_irqhandler(info->irq, info->netdev);
+       info->evtchn = info->irq = 0;
 }
 
 /* Stop network device and free tx/rx queues and irq. */
index d447c873fabf4afdf9ebf1e8c151bad5ca7bc4ce..25a1bbea25763bcd3989ae9f10b2c70cb5ca0c26 100644 (file)
@@ -35,7 +35,7 @@ typedef struct tpmif_st {
 
        /* Physical parameters of the comms window. */
        unsigned int evtchn;
-       unsigned int remote_evtchn;
+       unsigned int irq;
 
        /* The shared rings and indexes. */
        tpmif_tx_interface_t *tx;
index af93a6bdd47df7a438665fb5b56d3416689267d0..43c6f6e0cc46065b534e745421a21af8d5ccd59e 100644 (file)
@@ -120,8 +120,6 @@ tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
        evtchn_op_t op = {.cmd = EVTCHNOP_bind_interdomain };
        int err;
 
-       BUG_ON(tpmif->remote_evtchn);
-
        if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
                return -ENOMEM;
 
@@ -143,12 +141,11 @@ tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
        }
 
        tpmif->evtchn = op.u.bind_interdomain.port1;
-       tpmif->remote_evtchn = evtchn;
 
        tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
 
-       bind_evtchn_to_irqhandler(tpmif->evtchn,
-                                 tpmif_be_int, 0, "tpmif-backend", tpmif);
+       tpmif->irq = bind_evtchn_to_irqhandler(
+               tpmif->evtchn, tpmif_be_int, 0, "tpmif-backend", tpmif);
        tpmif->status = CONNECTED;
        tpmif->shmem_ref = shared_page;
        tpmif->active = 1;
@@ -159,18 +156,10 @@ tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
 static void
 __tpmif_disconnect_complete(void *arg)
 {
-       evtchn_op_t op = {.cmd = EVTCHNOP_close };
        tpmif_t *tpmif = (tpmif_t *) arg;
 
-       op.u.close.port = tpmif->evtchn;
-       op.u.close.dom = DOMID_SELF;
-       HYPERVISOR_event_channel_op(&op);
-       op.u.close.port = tpmif->remote_evtchn;
-       op.u.close.dom = tpmif->domid;
-       HYPERVISOR_event_channel_op(&op);
-
-       if (tpmif->evtchn)
-               unbind_evtchn_from_irqhandler(tpmif->evtchn, tpmif);
+       if (tpmif->irq)
+               unbind_evtchn_from_irqhandler(tpmif->irq, tpmif);
 
        if (tpmif->tx) {
                unmap_frontend_page(tpmif);
index 0bd6114f436e6f48b9cb1d8825180e8b398d9f1b..516aae330d7a5a8ae9358b54db5f8b1835d7fcb1 100644 (file)
@@ -292,8 +292,10 @@ static void destroy_tpmring(struct tpmfront_info *info, struct tpm_private *tp)
                free_page((unsigned long)tp->tx);
                tp->tx = NULL;
        }
-       unbind_evtchn_from_irqhandler(tp->evtchn, NULL);
-       tp->evtchn = 0;
+
+       if (tpm->irq)
+               unbind_evtchn_from_irqhandler(tp->irq, NULL);
+       tp->evtchn = tpm->irq = 0;
 }
 
 
@@ -501,10 +503,12 @@ static void tpmif_connect(u16 evtchn, domid_t domid)
        err = bind_evtchn_to_irqhandler(
                tp->evtchn,
                tpmif_int, SA_SAMPLE_RANDOM, "tpmif", tp);
-       if ( err != 0 ) {
+       if ( err <= 0 ) {
                WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
                return;
        }
+
+       tp->irq = err;
 }
 
 static struct xenbus_device_id tpmfront_ids[] = {
index 9c7f51a2bc3c3be454ea5a38b384c96fd3b26295..f5ddea0cbf1637e66da2f595ebca31f5d6645534 100644 (file)
@@ -5,7 +5,7 @@
 struct tpm_private
 {
        tpmif_tx_interface_t *tx;
-       unsigned int evtchn;
+       unsigned int evtchn, irq;
        int connected;
 
        spinlock_t tx_lock;
index e0052d7f482f0dda0aecf98fc1a7df3bd6788674..972236d285d4a1880038bfe7a8816354d42f1089 100644 (file)
@@ -44,6 +44,8 @@ struct ringbuf_head
        char buf[0];
 } __attribute__((packed));
 
+static int xenbus_irq;
+
 DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
 
 static inline struct ringbuf_head *outbuf(void)
@@ -205,33 +207,29 @@ int xb_init_comms(void)
 {
        int err;
 
+       if (xenbus_irq)
+               unbind_evtchn_from_irqhandler(xenbus_irq, &xb_waitq);
+       xenbus_irq = 0;
+
        if (!xen_start_info->store_evtchn)
                return 0;
 
        err = bind_evtchn_to_irqhandler(
                xen_start_info->store_evtchn, wake_waiting,
                0, "xenbus", &xb_waitq);
-       if (err) {
+       if (err <= 0) {
                printk(KERN_ERR "XENBUS request irq failed %i\n", err);
-               unbind_evtchn_from_irq(xen_start_info->store_evtchn);
                return err;
        }
 
+       xenbus_irq = err;
+
        /* FIXME zero out page -- domain builder should probably do this*/
        memset(mfn_to_virt(xen_start_info->store_mfn), 0, PAGE_SIZE);
 
        return 0;
 }
 
-void xb_suspend_comms(void)
-{
-
-       if (!xen_start_info->store_evtchn)
-               return;
-
-       unbind_evtchn_from_irqhandler(xen_start_info->store_evtchn, &xb_waitq);
-}
-
 /*
  * Local variables:
  *  c-file-style: "linux"
index 04500f485512e1766ce11d4c187594eb9500ddbf..59ca0d3080ea8c9ea9df4ab28147e810b798ec4a 100644 (file)
@@ -30,7 +30,6 @@
 
 int xs_init(void);
 int xb_init_comms(void);
-void xb_suspend_comms(void);
 
 /* Low level routines. */
 int xb_write(const void *data, unsigned len);
index 094d81870e76bd75e217446520699931f3d48d0e..1ac3f457bc4310bf45eaa14690f9baa7578ad051 100644 (file)
@@ -607,7 +607,6 @@ void xenbus_suspend(void)
        down(&xenbus_lock);
        bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
        bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev);
-       xb_suspend_comms();
 }
 
 void xenbus_resume(void)
index d364b0a4b516e601e3537d9b784abbdbb837a023..360388fec6b597c64ed9ec23a4c80508f5dee47b 100644 (file)
@@ -51,14 +51,21 @@ extern void unbind_virq_from_irq(int virq);
 extern int  bind_ipi_to_irq(int ipi);
 extern void unbind_ipi_from_irq(int ipi);
 
-/* Dynamically bind an event-channel port to Linux IRQ space. */
+/*
+ * Dynamically bind an event-channel port to Linux IRQ space.
+ * BIND:   Returns IRQ or error.
+ * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
+ */
 extern int  bind_evtchn_to_irq(unsigned int evtchn);
-extern void unbind_evtchn_from_irq(unsigned int evtchn);
+extern void unbind_evtchn_from_irq(unsigned int irq);
 
 /*
  * Dynamically bind an event-channel port to an IRQ-like callback handler.
  * On some platforms this may not be implemented via the Linux IRQ subsystem.
- * You *cannot* trust the irq argument passed to the callback handler.
+ * The IRQ argument passed to the callback handler is the same as returned
+ * from the bind call. It may not correspond to a Linux IRQ number.
+ * BIND:   Returns IRQ or error.
+ * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
  */
 extern int  bind_evtchn_to_irqhandler(
        unsigned int evtchn,
@@ -66,7 +73,7 @@ extern int  bind_evtchn_to_irqhandler(
        unsigned long irqflags,
        const char *devname,
        void *dev_id);
-extern void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id);
+extern void unbind_evtchn_from_irqhandler(unsigned int irq, void *dev_id);
 
 extern void irq_resume(void);